package com.jyt.utils;

import chinavision.yjf.MVSDK;
import chinavision.yjf.MVSDK.tSdkFrameHead;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

import com.sun.jna.Native;

public class GrabCallback extends JFrame {

	public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
			@Override
			public void run() {
				try {
					UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
				} catch (ClassNotFoundException | InstantiationException
					   | IllegalAccessException | UnsupportedLookAndFeelException ex) {
					ex.printStackTrace();
				}

                new GrabCallback().createAndShowGui();
            }
        });
	}

	private int mCameraHandle;
	private long mFrameBuffer;
	private MVSDK.CAMERA_SNAP_PROC mImageCallback;
	private long mWndHandle;
	
    private void createAndShowGui() {

		setTitle("GrabCallback");
		setSize(800, 600);
		setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		setVisible(true);

		mWndHandle = Native.getComponentID(this);
		
		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				if (mCameraHandle != 0) {
					// 注销回调
					MVSDK.Api.CameraSetCallbackFunction(mCameraHandle, null, 0);
			
					// 关闭相机
					MVSDK.Api.CameraUnInit(mCameraHandle);
			
					// 释放帧缓存
					MVSDK.Api.CameraAlignFree(mFrameBuffer);
				}

				super.windowClosing(e);
			}
		});

		if (!openCamera() ) {
			System.exit(0);
		}
	}

	private boolean openCamera() {

		// 枚举相机
		MVSDK.tSdkCameraDevInfo[] DevList = MVSDK.Api.CameraEnumerateDevice();
		int nDev = DevList.length;
		if (nDev < 1) {
			JOptionPane.showMessageDialog(null, "No camera was found!");
			return false;
		}

		MVSDK.tSdkCameraDevInfo DevInfo = DevList[0];

		// 打开相机
		int hCamera = 0;
		try {
			hCamera = MVSDK.Api.CameraInit(DevInfo, -1, -1);
		}
		catch (MVSDK.CameraException e) {
			JOptionPane.showMessageDialog(null, String.format("CameraInit Failed(%d): %s", e.errorCode, e.getMessage()));
			return false;
		}
		mCameraHandle = hCamera;

		// 获取相机特性描述
		MVSDK.tSdkCameraCapbility cap = MVSDK.Api.CameraGetCapability(hCamera);

		// 判断是黑白相机还是彩色相机
		boolean monoCamera = (cap.sIspCapacity.bMonoSensor != 0);

		// 黑白相机让ISP直接输出MONO数据，而不是扩展成R=G=B的24位灰度
		if (monoCamera) {
			MVSDK.Api.CameraSetIspOutFormat(hCamera, MVSDK.CAMERA_MEDIA_TYPE_MONO8);
		}

		// 相机模式切换成连续采集
		MVSDK.Api.CameraSetTriggerMode(hCamera, 0);

		// 手动曝光，曝光时间30ms
		MVSDK.Api.CameraSetAeState(hCamera, 0);
		MVSDK.Api.CameraSetExposureTime(hCamera, 30 * 1000);

		// 让SDK内部取图线程开始工作
		MVSDK.Api.CameraPlay(hCamera);

		// 计算RGB buffer所需的大小，这里直接按照相机的最大分辨率来分配
		int FrameBufferSize = cap.sResolutionRange.iWidthMax * cap.sResolutionRange.iHeightMax * (monoCamera ? 1 : 3);

		// 分配RGB buffer，用来存放ISP输出的图像
		// 备注：从相机传输到PC端的是RAW数据，在PC端通过软件ISP转为RGB数据（如果是黑白相机就不需要转换格式，但是ISP还有其它处理，所以也需要分配这个buffer）
		mFrameBuffer = MVSDK.Api.CameraAlignMalloc(FrameBufferSize, 16);

		// 设置取图回调
		mImageCallback = new MVSDK.CAMERA_SNAP_PROC() {
			@Override
			public void OnCaptured(int hCamera, long pRawBuffer, tSdkFrameHead pFrameHead, long Context) {
				MVSDK.Api.CameraImageProcess(hCamera, pRawBuffer, mFrameBuffer, pFrameHead);
				
				// 此时图片已经存储在pFrameBuffer中，对于彩色相机pFrameBuffer=RGB数据，黑白相机pFrameBuffer=8位灰度数据
				MVSDK.Api.CameraDrawFrameBuffer(mFrameBuffer, pFrameHead, mWndHandle, 0, 1);




			}
		};
		MVSDK.Api.CameraSetCallbackFunction(hCamera, mImageCallback, 0);
		
		return true;
	}
}
